package com.k2data.k2app.controller;

import com.github.pagehelper.PageHelper;
import com.k2data.k2app.constant.Constant;
import com.k2data.k2app.domain.SysMenu;
import com.k2data.k2app.domain.SysRole;
import com.k2data.k2app.domain.SysUser;
import com.k2data.k2app.domain.SysUserDTO;
import com.k2data.k2app.mapper.SysUserMapper;
import com.k2data.k2app.response.CommonResultResponse;
import com.k2data.k2app.response.PageInfo;
import com.k2data.k2app.response.ResponseHelper;
import com.k2data.k2app.service.SysMenuService;
import com.k2data.k2app.service.SysRoleService;
import com.k2data.k2app.service.SysUserService;
import com.k2data.k2app.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * 系统用户
 * Created by clb on 17-3-17.
 */
@Api(description = "系统用户")
@RestController
@RequestMapping("/users")
public class SysUserController {
	@Autowired
	private  SysUserMapper sysUserMapper;
	@Autowired
	private  SysUserService sysUserService;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private SysMenuService sysMenuService;

	private static String salt = "Abdk7B19c";  // TODO

	@ApiOperation(value = "创建")
	@ApiImplicitParam(name = "sysUser", value = "sysUser对象", required = true, dataType = "SysUser", paramType = "body")
	@PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<CommonResultResponse> post(@RequestBody SysUser sysUser) throws Exception {
		sysUser.setPassword(md5Password(sysUser.getPassword()));

		return ResponseHelper.success(sysUserService.insert(sysUser));
	}

	@ApiOperation(value = "更新")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
			@ApiImplicitParam(name = "sysUser", value = "sysUser对象", required = true, dataType = "SysUser", paramType = "body")
	})
	@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<CommonResultResponse> update(@PathVariable("id") Long id,
													   @RequestBody SysUser sysUser) throws Exception {
		sysUser.setId(id);

		if (!StringUtils.isBlank(sysUser.getPassword())) {
			sysUser.setPassword(md5Password(sysUser.getPassword()));
		}
		return ResponseHelper.success(sysUserService.update(sysUser));
	}

	@ApiOperation(value = "根据id查询")
	@ApiImplicitParam(name = "id", value = "the value of id", required = true, dataType = "Long", paramType = "path")
	@GetMapping(value = "/{id}")
	public ResponseEntity<CommonResultResponse> get(@PathVariable("id") Long id) throws Exception {
		return ResponseHelper.success(sysUserService.get(id));
	}

	@ApiOperation(value = "重置密码")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
			@ApiImplicitParam(name = "sysUser", value = "sysUser对象", required = true, dataType = "SysUser", paramType = "body")
	})
	@PutMapping(value = "/{id}/reset")
	public ResponseEntity<CommonResultResponse> resetPw(@PathVariable("id") Long id,
	                                                    @RequestBody SysUser sysUser) throws Exception {
		sysUser.setId(id);
		if (!StringUtils.isBlank(sysUser.getPassword())) {
			sysUser.setPassword(md5Password(sysUser.getPassword()));
		}
		sysUser.setUpdateBy("");
		return ResponseHelper.success(sysUserMapper.updateByPrimaryKeySelective(sysUser));
	}

	@ApiOperation(value = "删除(假删除)")
	@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
	@PostMapping(value = "/deleted/{id}")
	public ResponseEntity<CommonResultResponse> deleteFlag(@PathVariable("id") Long id) throws Exception {
		SysUser sysUser = new SysUser();
		sysUser.setIsDelete(Constant.YES);
		sysUser.setId(id);
		return ResponseHelper.success(sysUserMapper.updateDeletedFlag(sysUser));
	}

	@ApiOperation(value = "删除")
	@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
	@DeleteMapping(value = "/{id}")
	public ResponseEntity<CommonResultResponse> delete(@PathVariable("id") Long id) throws Exception {
		return ResponseHelper.success(sysUserService.deleteById(id));
	}

	@ApiOperation(value = "冻结登陆")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
			@ApiImplicitParam(name = "freeFlag", value = "冻结标志:(true:冻结 false:解除冻结)", required = true, dataType = "Boolean", paramType = "query")
	})

	@PostMapping(value = "/{id}/freeze")
	public ResponseEntity<CommonResultResponse> loginFlag(@PathVariable("id") Long id,
														  @RequestParam("freeFlag") boolean freeFlag) throws Exception {
		SysUser sysUser = new SysUser();
		if(freeFlag){
			sysUser.setLoginFlag(Constant.NO);
		}else{
			sysUser.setLoginFlag(Constant.YES);
		}
		sysUser.setId(id);
		return ResponseHelper.success(sysUserMapper.updateLoginFlag(sysUser));
	}

	@ApiOperation(value = "用户的角色")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "pageSize", value = "每页大小(默认 30)", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "Long", paramType = "path")
	})
	@GetMapping(value = "/{id}/roles")
	public ResponseEntity<CommonResultResponse> rolesById(@RequestParam(value = "pageNum", required = false) Integer pageNum,
														  @RequestParam(value = "pageSize", required = false) Integer pageSize,
														  @PathVariable("id") Long id) throws Exception {
		pageNum = pageNum == null ? 1 : pageNum;
		pageSize = pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize;
		PageHelper.startPage(pageNum, pageSize);
		List<SysRole> list = sysRoleService.getRolesByUser(id);
		int count = list.size();
		PageInfo pageInfo = new PageInfo(pageNum, pageSize, count);
		return ResponseHelper.success(list,pageInfo);
	}


	@ApiOperation(value = "验证密码")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "id", value = "the value of id", required = true, dataType = "Long", paramType = "path"),
			@ApiImplicitParam(name = "pwd", value = "用户密码", required = false, dataType = "String", paramType = "query"),
	})
	@PostMapping(value = "/{id}/confirmPwd")
	public ResponseEntity<CommonResultResponse> confirmPwd(@PathVariable("id") Long id,
														   @RequestParam(value = "pwd", required = true) String pwd) throws Exception {
		SysUser sysUser = new SysUser();
		sysUser.setPassword(md5Password(pwd));
		return ResponseHelper.success(sysUserService.confirmPwd(id,sysUser));
	}

	@ApiOperation(value = "获取所有记录")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "pageSize", value = "每页大小(默认 30)", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "loginName", value = "登陆名", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "name", value = "姓名", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "userType", value = "姓名", required = false, dataType = "String", paramType = "query")
	})
	@GetMapping(value = "")
	public ResponseEntity<CommonResultResponse> list(@RequestParam(value = "pageNum", required = false) Integer pageNum,
	                                                 @RequestParam(value = "pageSize", required = false) Integer pageSize,
	                                                 @RequestParam(value = "loginName", required = false) String loginName,
													 @RequestParam(value = "name", required = false) String name,
													 @RequestParam(value = "userType", required = false) String userType) throws Exception {
		SysUser sysUser = new SysUser();
		sysUser.setName(name);
		sysUser.setLoginName(loginName);
		sysUser.setUserType(userType);
		pageSize = pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize;
		pageNum = (pageNum == null) ? Integer.valueOf(1) : pageNum;
		PageHelper.startPage(pageNum, pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize);
		List<SysUser> list = sysUserService.list(sysUser);
		PageInfo pageInfo = new PageInfo(pageNum, pageSize, sysUserMapper.selectCount(sysUser));
		return ResponseHelper.success(list,pageInfo);
	}

	@ApiOperation(value = "用户的菜单")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "pageSize", value = "每页大小(默认 30)", dataType = "int", paramType = "query"),
			@ApiImplicitParam(name = "isTree", value = "是否返回树形结构(默认tree)", dataType = "Boolean", paramType = "query"),
			@ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "Long", paramType = "path")
	})
	@GetMapping(value = "/{id}/menus")
	public ResponseEntity<CommonResultResponse> menusById(@RequestParam(value = "pageNum", required = false) Integer pageNum,
														  @RequestParam(value = "pageSize", required = false) Integer pageSize,
														  @RequestParam(value = "isTree", required = false) Boolean isTree,
														  @PathVariable("id") Long id) throws Exception {
		pageNum = pageNum == null ? 1 : pageNum;
		pageSize = pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize;
		PageHelper.startPage(pageNum, pageSize);
		List<SysMenu> list = sysMenuService.getMenusByUser(id,isTree);
		int count = list.size();
		PageInfo pageInfo = new PageInfo(pageNum, pageSize, count);
		return ResponseHelper.success(list,pageInfo);
	}

    @ApiOperation(value = "single user")
    @GetMapping(value = "/auth")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "username", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "password", dataType = "String", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> user(
            @RequestParam(value = "username") @Valid @NotNull String username,
            @RequestParam(value = "password") @Valid @NotNull String password
    ) throws Exception {
        SysUser cond = new SysUser();
        cond.setLoginName(username);
        cond.setPassword(md5Password(password));

        SysUser user = sysUserMapper.selectOne(cond);

        if (user == null) {
            return ResponseHelper.success(new SysUserDTO());
        }

        SysUserDTO sysUserDTO = new SysUserDTO();
        sysUserDTO.setId(user.getId());
        sysUserDTO.setUsername(user.getLoginName());
        sysUserDTO.setPassword(user.getPassword());
        sysUserDTO.setLoginFlag(user.getLoginFlag());
        return ResponseHelper.success(sysUserDTO);
    }

    private String md5Password(String password) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] md5 = md.digest((salt + password).getBytes("UTF-8"));
        StringBuffer sb = new StringBuffer();
        for (byte aMd5 : md5) {
            sb.append(Integer.toHexString((aMd5 & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }
}
